package com.zhouyu.exampleThread.builder;

import java.util.concurrent.ThreadPoolExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.util.ErrorHandler;

/**
 * @Description:
 */
public class ThreadPoolBuilder {

  private static Logger logger = LoggerFactory.getLogger(ThreadPoolBuilder.class);

  /** 核心线程数 */
  private static final int CORE_POOL_SIZE = 8;
  /** 最大先线程数 */
  private static final int MAX_POOL_SIZE = 15;

  /** 非核心线程存活时间 */
  private static final int KEEP_ALIVE_SECONDS = 10;
  /** 任务队列大小 */
  private static final int QUEUE_CAPACITY = 80;

  private static final String COMOONLY_THREAD = "COMMONLY-THREAD-";
  private static final String SCHEDULE_THREAD = "SCHEDULE-THREAD-";

  /**
   * 常用线程池，@Async需要配置使用这个线程池
   */
  public static ThreadPoolTaskExecutor builCommonThreadPool() {
    ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
    threadPoolTaskExecutor.setCorePoolSize(CORE_POOL_SIZE);
    threadPoolTaskExecutor.setMaxPoolSize(MAX_POOL_SIZE);
    threadPoolTaskExecutor.setKeepAliveSeconds(KEEP_ALIVE_SECONDS);
    threadPoolTaskExecutor.setQueueCapacity(QUEUE_CAPACITY);
    threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
    threadPoolTaskExecutor.setThreadNamePrefix(COMOONLY_THREAD);
    //线程池的优雅停止，必须等所有的线程完成后关闭
    threadPoolTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
    //守护线程
    threadPoolTaskExecutor.setDaemon(true);
    return threadPoolTaskExecutor;
  }

  /**
   * 调度线程池, @Scheduled需要配配置使用这个线程池
   */
  public static ThreadPoolTaskScheduler builSchedulThreadPool() {
    ThreadPoolTaskScheduler poolTaskScheduler = new ThreadPoolTaskScheduler();
    poolTaskScheduler.setPoolSize(CORE_POOL_SIZE);
    poolTaskScheduler.setErrorHandler(new ErrorHandler() {
      @Override
      public void handleError(Throwable throwable) {
        logger.error("调度线程错误:{}", throwable);
      }
    });
    poolTaskScheduler.setWaitForTasksToCompleteOnShutdown(true);
    poolTaskScheduler.setThreadNamePrefix(SCHEDULE_THREAD);
    return poolTaskScheduler;
  }

}
